package com.jingxuan.controller;

import com.jingxuan.common.annotation.NoAuth;
import java.util.List;
import com.jingxuan.common.annotation.RequirePermission;
import com.jingxuan.common.annotation.RequireRole;
import com.jingxuan.common.exception.BusinessException;
import com.jingxuan.common.result.Result;
import com.jingxuan.common.result.ResultCode;
import com.jingxuan.dto.request.UpdatePasswordRequest;
import com.jingxuan.dto.request.UserLoginRequest;
import com.jingxuan.dto.request.UserRegisterRequest;
import com.jingxuan.dto.request.UserUpdateRequest;
import com.jingxuan.dto.response.LoginResponse;
import com.jingxuan.dto.response.UserInfoResponse;
import com.jingxuan.interceptor.AuthInterceptor;
import com.jingxuan.service.UserService;
import com.jingxuan.util.CheckValidPhone;
import com.jingxuan.util.JwtUtil;

import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private JwtUtil jwtUtil;

    /**
     * 用户注册
     * POST /users
     */
    @NoAuth
    @PostMapping
    public Result<UserInfoResponse> register(@Valid @RequestBody UserRegisterRequest request) {
        log.info("用户注册请求，phone: {}", request.getPhone());

        // 验证手机号格式
        if (!CheckValidPhone.isValidPhone(request.getPhone())) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "手机号格式不正确");
        }

        UserInfoResponse response = userService.register(request);
        return Result.success(response);
    }

    /**
     * 用户登录
     * POST /users/login
     */
    @NoAuth
    @PostMapping("/login")
    public Result<LoginResponse> login(@Valid @RequestBody UserLoginRequest request) {
        log.info("用户登录请求，phone: {}", request.getPhone());

        // 验证手机号
        if (!CheckValidPhone.isValidPhone(request.getPhone())) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "手机号格式不正确");
        }

        // 登录验证并获取用户信息
        UserInfoResponse userInfo = userService.login(request);

        // 生成JWT Token，将角色信息写入token
        String roles = String.join(",", userInfo.getRoles());
        String token = jwtUtil.generateToken(
                userInfo.getUserId(),
                userInfo.getUserName(),
                roles);

        // 构建登录响应
        LoginResponse loginResponse = new LoginResponse();
        loginResponse.setToken(token);
        loginResponse.setUserId(userInfo.getUserId());
        loginResponse.setUserName(userInfo.getUserName());
        loginResponse.setPhone(userInfo.getPhone());
        loginResponse.setIcon(userInfo.getIcon());
        loginResponse.setBirthdate(userInfo.getBirthdate());
        loginResponse.setPreferences(userInfo.getPreferences());
        loginResponse.setRoles(userInfo.getRoles());
        loginResponse.setPermissions(userInfo.getPermissions());

        log.info("用户登录成功，userId: {}, token已生成", userInfo.getUserId());
        return Result.success(loginResponse);
    }

    /**
     * 获取当前用户信息
     * GET /users/me
     */
    @GetMapping("/me")
    public Result<UserInfoResponse> getCurrentUser() {
        Long userId = AuthInterceptor.getCurrentUserId();
        log.info("获取当前用户信息，userId: {}", userId);
        UserInfoResponse response = userService.getUserById(userId);
        return Result.success(response);
    }

    /**
     * 获取指定用户信息（管理员权限）
     * GET /users/{userId}
     */
    @RequireRole("ROLE_ADMIN") // 只有管理员可以查看其他用户信息
    @GetMapping("/{userId}")
    public Result<UserInfoResponse> getUserById(@PathVariable Long userId) {
        log.info("管理员查看用户信息，userId: {}", userId);
        UserInfoResponse response = userService.getUserById(userId);
        return Result.success(response);
    }

    /**
     * 获取用户列表（管理员权限）
     * GET /users
     */
    @RequireRole("ROLE_ADMIN")
    @GetMapping
    public Result<List<UserInfoResponse>> getUserList(@RequestParam(required = false) String keyword) {
        log.info("管理员获取用户列表，keyword: {}", keyword);
        List<UserInfoResponse> list = userService.getUserList(keyword);
        return Result.success(list);
    }

    /**
     * 获取管理员列表（管理员权限）
     * GET /users/admins
     */
    @RequireRole("ROLE_ADMIN")
    @GetMapping("/admins")
    public Result<List<UserInfoResponse>> getAdminList(@RequestParam(required = false) String keyword) {
        log.info("管理员获取管理员列表，keyword: {}", keyword);
        List<UserInfoResponse> list = userService.getAdminList(keyword);
        return Result.success(list);
    }

    /**
     * 创建管理员（管理员权限）
     * POST /users/admins
     */
    @RequireRole("ROLE_ADMIN")
    @PostMapping("/admins")
    public Result<UserInfoResponse> createAdmin(@Valid @RequestBody UserRegisterRequest request) {
        log.info("管理员创建管理员，phone: {}", request.getPhone());
        // 验证手机号格式
        if (!CheckValidPhone.isValidPhone(request.getPhone())) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "手机号格式不正确");
        }
        UserInfoResponse response = userService.createAdmin(request);
        return Result.success(response);
    }

    /**
     * 更新用户信息
     * PUT /users/{userId}
     */
    @RequirePermission("user:write") // 需要用户编辑权限
    @PutMapping("/{userId}")
    public Result<UserInfoResponse> updateUser(@PathVariable Long userId,
            @Valid @RequestBody UserUpdateRequest request) {
        Long currentUserId = AuthInterceptor.getCurrentUserId();

        // 非管理员只能修改自己的信息
        if (!userId.equals(currentUserId)) {
            String roles = AuthInterceptor.getCurrentUserRoles();
            if (roles == null || !roles.contains("ROLE_ADMIN")) {
                throw new BusinessException(ResultCode.FORBIDDEN, "只能修改自己的信息");
            }
        } else {
            // 如果是修改自己的信息，不允许修改状态
            // 只有管理员可以修改状态，且管理员修改他人信息时可以修改状态
            // 这里简单处理：如果不是管理员，强制设置status为null，防止普通用户修改自己状态
            String roles = AuthInterceptor.getCurrentUserRoles();
            if (roles == null || !roles.contains("ROLE_ADMIN")) {
                request.setStatus(null);
            }
        }

        log.info("更新用户信息，userId: {}, operator: {}", userId, currentUserId);
        UserInfoResponse response = userService.updateUser(userId, request);
        return Result.success("更新成功", response);
    }

    /**
     * 用户修改密码
     * PUT /users/{userId}/pwd
     */
    @PutMapping("/{userId}/pwd")
    public Result<UserInfoResponse> updatePwd(@PathVariable Long userId,
            @Valid @RequestBody UpdatePasswordRequest request) {
        Long currentUserId = AuthInterceptor.getCurrentUserId();

        // 只能修改自己的密码
        if (!userId.equals(currentUserId)) {
            throw new BusinessException(ResultCode.FORBIDDEN, "只能修改自己的密码");
        }

        log.info("用户修改密码，userId: {}", userId);
        UserInfoResponse response = userService.updatePassword(userId, request);
        return Result.success("密码修改成功", response);
    }

    /**
     * 删除用户（管理员权限）
     * DELETE /users/{userId}
     */
    @RequireRole(value = "ROLE_ADMIN") // 管理员可以删除用户
    @RequirePermission(value = "user:delete") // 同时需要删除权限
    @DeleteMapping("/{userId}")
    public Result<Void> deleteUser(@PathVariable Long userId) {
        Long currentUserId = AuthInterceptor.getCurrentUserId();
        log.info("管理员删除用户，userId: {}, operator: {}", userId, currentUserId);
        userService.deleteUser(userId);

        return Result.success("删除成功", null);
    }

    /**
     * 更新用户偏好
     * PUT /users/{userId}/preferences
     */
    @RequireRole({ "ROLE_USER", "ROLE_ADMIN" })
    @PutMapping("/{userId}/preferences")
    public Result<UserInfoResponse> updateUserPreferences(@PathVariable Long userId,
            @Valid @RequestBody UserUpdateRequest preferences) {
        Long currentUserId = AuthInterceptor.getCurrentUserId();
        log.info("更新用户偏好，userId: {}, operator: {}", userId, currentUserId);
        UserInfoResponse response = userService.updateUserPreferences(userId, preferences);
        return Result.success(response);
    }
}
